<?php
namespace App\Components;

use Enqueue\Redis\RedisConnectionFactory;
use Enqueue\Redis\RedisContext;
use Predis\Client;

class Redis
{
    public static function __callStatic(string $name, array $arguments)
    {
        $client = new Client($_ENV['redis']);
        return $client->$name(...$arguments);
        // if ($response === null) {
        //     return $response;
        // }
        // return $response->getPayload();
    }

    private function __construct()
    {
    }
    private function __clone()
    {
    }
    private function __wakeup()
    {
    }

    /**
     * 随机秒级时间
     * @param int $level 时间范围 1=10秒, 2=30秒, 3=60秒
     * @return int 单位秒
     */
    public static function tinyTime(int $level = 0): int
    {
        $second = 0;
        switch ($level) {
            case 1:
                // 10秒左右 - 5秒钟,15秒钟
                $second = mt_rand(5, 15);
                break;
            case 2:
                // 30秒左右 - 20秒,40秒
                $second = mt_rand(20, 40);
                break;
            case 3:
                // 60秒左右 - 50秒,70秒
                $second = mt_rand(50, 70);
                break;
            default:
                $second = mt_rand(1, 60);
                break;
        }
        return $second;
    }

    /**
     * 随机分钟级时间
     * @param int $level 时间范围 1=2分钟, 2=5分钟, 3=10分钟, 4=15分钟, 5=20分钟
     * @return int 单位秒
     */
    public static function smallTime(int $level = 0): int
    {
        $second = 0;
        switch ($level) {
            case 1:
                // 2分钟左右 - 1分钟,3分钟
                $second = mt_rand(60, 180);
                break;
            case 2:
                // 5分钟左右 - 3分钟,7分钟
                $second = mt_rand(180, 420);
                break;
            case 3:
                // 10分钟左右 - 7分钟,13分钟
                $second = mt_rand(420, 780);
                break;
            case 4:
                // 15分钟左右 - 11分钟,19分钟
                $second = mt_rand(660, 1140);
                break;
            case 5:
                // 20分钟左右 - 15分钟,25分钟
                $second = mt_rand(900, 1500);
                break;
            default:
                $second = mt_rand(60, 600);
                break;
        }
        return $second;
    }

    /**
     * 随机小时级时间
     * @param int $level 时间范围 1=1小时, 2=2小时, 3=3小时, 4=4小时, 5=5小时, 6=6小时
     * @return int 单位秒
     */
    public static function mediumTime(int $level = 0): int
    {
        $minute = 0;
        switch ($level) {
            case 1:
                // 1小时左右 - 30分钟,90分钟
                $minute = mt_rand(30, 90);
                break;
            case 2:
                // 2小时左右 - 90分钟,150分钟
                $minute = mt_rand(90, 150);
                break;
            case 3:
                // 3小时左右 - 150分钟,210分钟
                $minute = mt_rand(150, 210);
                break;
            case 4:
                // 4小时左右 - 210分钟,270分钟
                $minute = mt_rand(210, 270);
                break;
            case 5:
                // 5小时左右 - 270分钟,330分钟
                $minute = mt_rand(270, 330);
                break;
            case 6:
                // 6小时左右 - 330分钟,390分钟
                $minute = mt_rand(330, 390);
                break;
            default:
                $minute = mt_rand(50, 350);
                break;
        }
        return $minute * mt_rand(58, 62);
    }

    /**
     * 同步锁 阻塞
     * @param string $lockName 锁名称   必须确保锁名称唯一
     * @param int $frequency 重试次数
     * @param int $interval 重试间隔 (单位微秒)
     * @return boolean 是否抢到锁 (抢到锁返回true)
     */
    public static function synchronizationLock(string $lockName, int $frequency = 10, int $interval = 600): bool
    {
        if ($frequency <= 0 || $interval <= 0) {
            return false;
        }

        $isExist = false;
        for ($i = 0; $i < $frequency; $i++) {
            $isExist = self::setnx($lockName, 1);
            if ($isExist === 1) {
                $isExist = true;

                self::expire($lockName, 3);
                break;
            } else {
                $isExist = false;
                usleep($interval);
            }
        }
        return $isExist;
    }

    /**
     * Redis消息队列环境
     */
    public static function queueContext(): RedisContext
    {
        $connection = new RedisConnectionFactory(array_merge(
            $_ENV['redis'],
            ['scheme_extensions' => ['predis']]
        ));
        return $connection->createContext();
    }
}
